const child_process_1 = require("child_process");
const netstring = require('netstring');
const fs = require("fs");
let spawnBin = '/home/wchi/Desktop/transport-worker';
let spawnArgs = [];

let producerSocket;
let consumerSocket;
let producerPayloadSocket;

let videoData;
function loadVideoData(fileName){
    return new Promise(((resolve, reject) => {
        fs.readFile(fileName,'binary',function(err,data){
            if(err){
                console.log(err)
                reject();
            }else{
                resolve(data);
            }
        });
    }))
}

let initPipeIndex = 7;
let pipeLength = 20;
let _child;
async function init(){
    let stdioList = ['ignore', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe']
    for (let i = 0; i < pipeLength; i++) {
        stdioList.push('pipe');
    }

    _child = child_process_1.spawn(
        // command
        spawnBin,
        // args
        spawnArgs,
        // options
        {
            env: {
                MEDIASOUP_VERSION: '3.7.15',
                // Let the worker process inherit all environment variables, useful
                // if a custom and not in the path GCC is used so the user can set
                // LD_LIBRARY_PATH environment variable for runtime.
                ...process.env
            },
            detached: false,
            // fd 0 (stdin)   : Just ignore it.
            // fd 1 (stdout)  : Pipe it for 3rd libraries that log their own stuff.
            // fd 2 (stderr)  : Same as stdout.
            // fd 3 (channel) : Producer Channel fd.
            // fd 4 (channel) : Consumer Channel fd.
            // fd 5 (channel) : Producer PayloadChannel fd.
            // fd 6 (channel) : Consumer PayloadChannel fd.
            stdio: stdioList,
            windowsHide: true
        });

    producerSocket = _child.stdio[3];
    consumerSocket = _child.stdio[4];
    producerPayloadSocket = _child.stdio[5];

    videoData = await loadVideoData('media/1.rgb');

    consumerSocket.on('data', buffer =>{
        if (buffer.byteLength < 300) {
            console.log('receive data:' + buffer.toString());
        }else{
            console.log('receive data, length:' + buffer.byteLength);
        }
    });

    _child.on('exit', (code, signal) => {
        this._child = undefined;
        // this.close();
        console.log('fail to start process,exit', code, signal);
    });

    _child.on('error', (error) => {
        this._child = undefined;
        this.close();
        console.log('fail to start process,error', error);
    });

// Be ready for 3rd party worker libraries logging to stdout.
    _child.stdout.on('data', (buffer) => {
        for (const line of buffer.toString('utf8').split('\n')) {
            if (line)
                console.log(`(stdout) ${line}`);
        }
    });
// In case of a worker bug, mediasoup will log to stderr.
    _child.stderr.on('data', (buffer) => {
        for (const line of buffer.toString('utf8').split('\n')) {
            if (line)
                console.log(`(stderr) ${line}`);
        }
    });
}

async function main(){
    try {
        await init();

        //初始化20个pipe
        for (let i = 1; i < 3; i++) {
            addConfig(i);

            const producerPayloadSocket = _child.stdio[initPipeIndex];
            //周期发送视频数据
            setInterval(async () => {
                writeMsg({id: i, type: 'video'}, producerPayloadSocket);
                await writeImage(videoData, producerPayloadSocket);
            }, 40);
            initPipeIndex += 2;
        }
    }catch (e) {
        console.log('fail to start main', e);
    }
}

function addConfig(id){
    let configMsg = {
        id,
        type:'config',
        audio:{},
        video:{},
        forward:{
            url:"http://www.baidu.com"
        }
    }

    //发送配置消息
    writeMsg(configMsg, producerSocket);
}

function writeMsg(obj, socket) {
    const ns = netstring.nsWrite(JSON.stringify(obj));
    socket.write(ns);
}

async function writeImage(fileData, socket){
    const ns = netstring.nsWrite(fileData);
    socket.write(ns);
}

main();
